﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace AnimatedSprites
{
    abstract class Sprite
    {
        // Save a reference to the sprite manager to
        // use to get the player position
        public InGameManager spriteManager;

        // Stuff needed to draw the sprite
        protected Texture2D textureImage;
        protected Point frameSize;
        protected float scale = 1;
        protected float originalScale = 1;       
        public Vector2 logicalPosition;
        public Vector2 viewPosition;
        public Vector2 offset = new Vector2(512,384);
        
        // Speed stuff
        protected Vector2 originalSpeed;

        // Collision data
        int collisionOffset;

        // Movement data
        protected Vector2 speed;
        protected Vector2 maxSpeed = new Vector2(15,15);

        // Sound stuff
        public string collisionCueName { get; private set; }

        const int defaultMillisecondsPerFrame = 16;

        // Abstract definition of direction property
        public abstract Vector2 direction
        {
            get;
        }

        // Get current position of the sprite
        public Vector2 GetPosition
        {
            get { return logicalPosition; }
        }
        

        // Get/set score
        public int scoreValue { get; protected set; }

        public Sprite(Texture2D textureImage, Vector2 logicalPosition, Point frameSize,
            int collisionOffset, Vector2 speed,
            string collisionCueName, int scoreValue, InGameManager IGM)
        {
            this.textureImage = textureImage;
            this.logicalPosition = logicalPosition;
            this.frameSize = frameSize;
            this.collisionOffset = collisionOffset;
            this.speed = speed;
            this.collisionCueName = collisionCueName;
            this.scoreValue = scoreValue;
            this.spriteManager = IGM;
            this.viewPosition = this.logicalPosition;
        }
        //*****constructor

        public virtual void Update()
        {/* do nothing */}

        public virtual void Update(GameTime gameTime, Rectangle clientBounds)
        {/* do nothing */}

        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch, Vector2 midPoint, bool chosen)
        {
            viewPosition = logicalPosition - (midPoint - offset);
            spriteBatch.Draw(textureImage,
                viewPosition,
                new Rectangle(0,
                    0,
                    frameSize.X, frameSize.Y),
                    chosen?Color.White:Color.Orange, 0, Vector2.Zero,
    
            scale, SpriteEffects.None, 0);
   
        }

        // Gets the collision rect based on position, framesize and collision offset
        public Rectangle collisionRect
        {
            get
            {
                return new Rectangle(
                    (int)(logicalPosition.X + (collisionOffset * scale)),
                    (int)(logicalPosition.Y + (collisionOffset * scale)),
                    (int)((frameSize.X - (collisionOffset * 2)) * scale),
                    (int)((frameSize.Y - (collisionOffset * 2)) * scale));
            }
        }

        // Detect if this sprite is off the screen and irrelevant
        public bool IsOutOfBounds(Rectangle clientRect)
        {
            if (logicalPosition.X < -frameSize.X ||
                logicalPosition.X > clientRect.Width ||
                logicalPosition.Y < -frameSize.Y ||
                logicalPosition.Y > clientRect.Height)
            {
                return true;
            }

            return false;
        }

        public void ModifyScale(float modifier)
        {
            scale *= modifier;
        }
        
        public void ResetScale()
        {
            scale = originalScale;
        }
        
        public void ModifySpeed(float modifier)
        {
            speed *= modifier;
        }
    
        public void ResetSpeed()
        {
            speed = originalSpeed;
        }
    }
}
